home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved.
- *
- * (b) If this Sample Code is distributed as part of the Display PostScript
- * System Software Development Kit from Adobe Systems Incorporated,
- * then this copy is designated as Development Software and its use is
- * subject to the terms of the License Agreement attached to such Kit.
- *
- * (c) If this Sample Code is distributed independently, then the following
- * terms apply:
- *
- * (d) This file may be freely copied and redistributed as long as:
- * 1) Parts (a), (d), (e) and (f) continue to be included in the file,
- * 2) If the file has been modified in any way, a notice of such
- * modification is conspicuously indicated.
- *
- * (e) PostScript, Display PostScript, and Adobe are registered trademarks of
- * Adobe Systems Incorporated.
- *
- * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
- * CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
- * AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
- * ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
- * OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
- * WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
- * WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
- * DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
- * OF THIRD PARTY RIGHTS.
- */
-
- /*
- * NXEPSImageRepSub.m
- *
- * A subclass of NXEPSImageRep. Enhanced to handle rotation
- * and resources.
- *
- * Version: 2.0
- * Author: Ken Fromm
- */
-
- #import "NXEPSImageRepSub.h"
-
- #import <appkit/Font.h>
- #import <appkit/Panel.h>
- #import <appkit/View.h>
- #import <appkit/nextstd.h>
- #import <appkit/defaults.h>
-
- #import <objc/List.h>
- #import <objc/Storage.h>
- #import <objc/hashtable.h>
- #import <dpsclient/wraps.h>
- #import <stdio.h>
-
- /* Used only for demonstration purposes. */
- #import "ImportApp.h"
- #import "epsfwraps.h"
-
- @implementation NXEPSImageRepSub
-
- - free
- {
- if (_tempName)
- NX_FREE(_tempName);
-
- return [super free];
- }
-
- - writeIncludedFiles:storage;
- {
- int i, count,
- writelen, readlen, includelen, maxlen;
-
- char *readdata, *startdata, *includedata;
-
- NXStream *writestream, *readstream, *includestream;
-
- Inclusion *inclusion;
-
- if (storage && [storage count])
- {
- readlen = 0;
- readdata = NULL;
- readstream = NULL;
- if (_fileName)
- {
- readstream = NXMapFile(_fileName, NX_READONLY);
- if (readstream)
- NXGetMemoryBuffer(readstream, &readdata, &readlen, &maxlen);
- }
- else
- {
- readdata = _memory;
- readlen = _epsLen;
- }
-
- if (readdata && readlen)
- {
- startdata = readdata;
- if (_fileName)
- writestream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- else
- writestream = NXOpenMemory(NULL, 0, NX_READWRITE);
- if (writestream)
- {
- count = [storage count];
- for (i = 0; i < count; i++)
- {
- inclusion = [storage elementAt:i];
- if (inclusion->filename && inclusion->len)
- {
- writelen = inclusion->offset - (readdata - startdata);
- NXWrite(writestream, readdata, writelen);
- includestream = NXMapFile(inclusion->filename, NX_READONLY);
- if (includestream)
- {
- NXGetMemoryBuffer(includestream, &includedata,
- &includelen, &maxlen);
- NXWrite(writestream, includedata, includelen);
- }
- else
- NXWrite(writestream, readdata+inclusion->offset,
- inclusion->len);
- readdata += writelen + inclusion->len;
- readlen -= (writelen + inclusion->len);
- }
- }
- NXWrite(writestream, readdata, readlen);
-
- if (_fileName)
- {
- _tempName = NXCopyStringBuffer("/tmp/EpsfTempXXXXXX.eps");
- NXGetTempFilename(_tempName, 13);
- if (_tempName)
- NXSaveToFile(writestream, _tempName);
- NXCloseMemory(writestream, NX_FREEBUFFER);
- }
- else
- {
- NXGetMemoryBuffer(writestream, &_tempMemory,
- &_tempEpsLen, &maxlen);
- NXCloseMemory(writestream, NX_SAVEBUFFER);
- }
- }
- }
-
- if (readstream)
- NXCloseMemory(readstream, NX_FREEBUFFER);
- }
-
- return self;
- }
-
- /*
- * Check to see if the fonts are on the system and only flag
- * those not available.
- */
- - checkFonts:(Resource *) resource placeIn:(ResourceList *) resourceList
- {
- id font;
-
- int i, count;
-
- if (resource && resourceList)
- {
- if (resource->states[RES_NEEDED])
- resourceList->types[RES_FONTS] = [resource->states[RES_NEEDED] copy];
- else if (!resource->states[RES_SUPPLIED] && resource->states[RES_PRESENT])
- resourceList->types[RES_FONTS] = [resource->states[RES_PRESENT] copy];
-
- /*
- * There should be an easier way to check for font availability other
- * than to create a font object but this will have to do for now.
- */
- count = [resourceList->types[RES_FONTS] count];
- for (i = count -1; i >= 0; i--)
- {
- font = [Font newFont:(char *) [resourceList->types[RES_FONTS] objectAt:i] size:12];
- if (font)
- {
- [font free];
- [resourceList->types[RES_FONTS] removeObjectAt:i];
- }
- }
-
- if ([resourceList->types[RES_FONTS] count] == 0)
- {
- [resourceList->types[RES_FONTS] free];
- resourceList->types[RES_FONTS] = NULL;
- }
- }
-
- return self;
- }
-
- - checkFiles:(Resource *) resource placeIn:(ResourceList *) resourceList
- {
- int i, count;
-
- FILE *file;
-
- if (resource && resourceList)
- {
- if (resource->states[RES_NEEDED])
- resourceList->types[RES_FILES] = [resource->states[RES_NEEDED] copy];
-
- /*
- * Try to open the files. If available then remove from the list.
- */
- count = [resourceList->types[RES_FILES] count];
- for (i = count -1; i >= 0; i--)
- {
- file = fopen((char *) [resourceList->types[RES_FILES] objectAt:i], "r");
- if (file)
- {
- fclose(file);
- [resourceList->types[RES_FILES] removeObjectAt:i];
- }
- }
-
- if ([resourceList->types[RES_FILES] count] == 0)
- {
- [resourceList->types[RES_FILES] free];
- resourceList->types[RES_FILES] = NULL;
- }
- }
-
- return self;
- }
-
- - checkProcSets:(Resource *) resource placeIn:(ResourceList *) resourceList
- {
- if (resource && resourceList)
- {
- if (resource->states[RES_NEEDED])
- resourceList->types[RES_PROCSETS] = [resource->states[RES_NEEDED] copy];
- }
-
- return self;
- }
-
- - checkPatterns:(Resource *) resource placeIn:(ResourceList *) resourceList
- {
- if (resource && resourceList)
- {
- if (resource->states[RES_NEEDED])
- resourceList->types[RES_PATTERNS] = [resource->states[RES_NEEDED] copy];
- }
-
- return self;
- }
-
- - checkForms:(Resource *) resource placeIn:(ResourceList *) resourceList
- {
- if (resource && resourceList)
- {
- if (resource->states[RES_NEEDED])
- resourceList->types[RES_FORMS] = [resource->states[RES_NEEDED] copy];
- }
-
- return self;
- }
-
- /*
- * Fills in the empty resources and inclusions array within the epsf structure.
- */
- - (int) getResources:(EpsfStruct *) epsf
- {
- int maxlen, error;
-
- NXStream *stream;
-
- error = EPSF_INVALIDPS;
- if (epsf)
- {
- stream = NULL;
- epsf->filedata = NULL;
- if (_fileName)
- {
- stream = NXMapFile(_fileName, NX_READONLY);
- if (stream)
- NXGetMemoryBuffer(stream, &epsf->filedata, &epsf->filelen, &maxlen);
- }
- else
- {
- epsf->filedata = _memory;
- epsf->filelen = _epsLen;
- }
-
- if (epsf->filedata)
- error = ReadEpsf(epsf);
-
- if (stream)
- NXCloseMemory(stream, NX_FREEBUFFER);
- }
-
- return error;
- }
-
- /*
- * Returns the list of unavailableResources.
- *
- * Returns any resources except for fonts that are marked as needed.
- * Check to see if the fonts are on the system and flags only those not
- * available. As the other resources move into the realm of system
- * resources, this method can check the availability of these resources
- * as well.
- *
- */
- - checkResources:(ResourceList *) resourceList;
- {
- int error;
-
- EpsfStruct epsf;
-
- bzero(resourceList, sizeof(ResourceList));
- error = [self getResources:&epsf];
- if (!error)
- {
- [self checkFonts:&epsf.resources[RES_FONTS] placeIn:resourceList];
- [self checkFiles:&epsf.resources[RES_FILES] placeIn:resourceList];
- [self checkProcSets:&epsf.resources[RES_PROCSETS] placeIn:resourceList];
- [self checkPatterns:&epsf.resources[RES_PATTERNS] placeIn:resourceList];
- [self checkForms:&epsf.resources[RES_FORMS] placeIn:resourceList];
-
- [self writeIncludedFiles:epsf.inclusions];
-
- return self;
- }
- else
- Notify("Import Error", ErrorEpsf(error));
-
- return nil;
- }
-
- /*
- * Used when printing. Add the resources used in this file
- * to the list passed in. Only adds the resources that are not
- * currently in the resourceDoc structure already.
- */
- - addResources:(Resource *) resourceDoc forFile:(NXAtom) fileName
- {
- id name;
-
- int i, j, k, count;
-
- EpsfStruct epsf;
-
- if (_fileName || fileName)
- {
- i = RES_SUPPLIED;
- if (_fileName)
- {
- name = (id) _fileName;
- if (NXDrawingStatus == NX_COPYING)
- i = RES_NEEDED;
- }
- else
- name = (id) fileName;
-
- if (!resourceDoc[RES_FILES].states[RES_PRESENT])
- resourceDoc[RES_FILES].states[RES_PRESENT] = [List new];
- if (!resourceDoc[RES_FILES].states[RES_NEEDED])
- resourceDoc[RES_FILES].states[i] = [List new];
-
- [resourceDoc[RES_FILES].states[RES_PRESENT] addObjectIfAbsent:name];
- [resourceDoc[RES_FILES].states[i] addObjectIfAbsent:name];
- }
-
- [self getResources:&epsf];
- for (i = 0; i < RES_NUMTYPES; i++)
- {
- for (j = 0; j < RES_NUMSTATES; j++)
- {
- if (epsf.resources[i].states[j])
- {
- if (!resourceDoc[i].states[j])
- resourceDoc[i].states[j] = [List new];
-
- count = [epsf.resources[i].states[j] count];
- for (k = 0; k < count; k++)
- [resourceDoc[i].states[j]
- addObjectIfAbsent:[epsf.resources[i].states[j] objectAt:k]];
- }
- }
- }
-
- return self;
- }
-
- /*
- * Overridden to handle any %%IncludeFile. A temporary file or
- * memory buffer has been written out that adds the included
- * files. This temporary file or memory pointer are swapped for the
- * real ones if they exist. The image is drawn and then they are
- * returned back. Their is probably a better way but without
- * knowing the internals of how this class works its a tenuous
- * bet to find one.
- */
- - (BOOL) draw
- {
- BOOL rc = YES;
-
- char *data,
- *tempname,
- *tempmemory;
-
- int templen, len, maxlen;
-
- NXStream *stream;
-
- templen = 0;
- tempname = tempmemory = NULL;
- if (_tempName || _tempMemory)
- {
- if (_fileName)
- {
- tempname = _fileName;
- _fileName = _tempName;
- }
- else
- {
- tempmemory = _memory;
- templen = _epsLen;
- _memory = _tempMemory;
- _epsLen = _tempEpsLen;
- }
- }
-
- /*************************************************************
- * The first case of the if-else statement is only to show
- * what can happen when a separate context is not used.
- * The imaging should be done with the draw method
- * because it installs a separate context.
- **************************************************************/
- if (![NXApp contextFlag])
- {
- PStranslate(-_bBoxOrigin.x, -_bBoxOrigin.y);
- if (_fileName && !_repFlags.dataLoaded)
- {
- stream = NXMapFile(_fileName, NX_READONLY);
- if (stream)
- NXGetMemoryBuffer(stream, &data, &len, &maxlen);
- }
- else
- {
- data = _memory;
- len = _epsLen;
- }
-
- PSWBeginEpsf();
- DPSWritePostScript(DPSGetCurrentContext(), data, len);
- PSWEndEpsf();
- }
- else
- rc = [super draw];
-
- if (_tempName || _tempMemory)
- {
- if (_fileName)
- {
- _fileName = tempname;
- }
- else
- {
- _memory = tempmemory;
- _epsLen = templen;
- }
- }
-
- return rc;
- }
-
- /*
- * Draws the EPS file. Positions it appropriately, scaling and rotating
- * it according to the arguments passed in. The rotation is in degrees.
- */
- - (BOOL) drawIn:(NXRect *) r with:(float) rotation
- {
- BOOL error;
-
- NXRect original;
-
- error = NO;
- if (NXDrawingStatus == NX_COPYING)
- {
- original.origin = _bBoxOrigin;
- original.size = size;
- if (_fileName)
- {
- WriteEpsfIllustratorBeg(r, &original, rotation, _fileName);
- WriteEpsfIllustratorInclude(_fileName);
- WriteEpsfIllustratorEnd();
- }
- else
- {
- WriteEpsfIllustratorBeg(r, &original, rotation, NULL);
- DPSWritePostScript(DPSGetCurrentContext(), _memory, _epsLen);
- WriteEpsfIllustratorEnd();
- }
- }
- else
- {
- PSgsave();
- PStranslate(r->origin.x, r->origin.y);
- PSrotate(rotation);
- PSscale(r->size.width/size.width, r->size.height/size.height);
-
- error = [self draw];
- PSgrestore();
- }
-
- return error;
- }
-
- @end
-